<?php
/**
 * Created by PhpStorm.
 * User: admin
 * Date: 2019/11/7
 * Time: 14:12
 */

namespace app\api\service;


use app\adminapiv3\service\platform_manage\ServerAuthService;
use app\common\exception\CustomException;
use app\common\service\Host;
use app\common\service\platform_manage\log\ServerUpdateLogService;
use app\common\service\ServerVersion;
use think\Db;
use think\exception\ValidateException;

class ProductUpdate extends BaseService
{
    /**
     * @name 同时在线下载数
     * @param int $limit
     * @author wx
     * @date 2019/11/7 14:44
     */
    public function online($limit = 20)
    {
        $count = Db::name('server_update')->where('status',1)->count();
        if ($limit >= $count) {
            return true;
        }else{
            return false;
        }
    }

    /**
     * @name 返回更新包路径
     * @param $data
     * @return bool|mixed
     * @author wx
     * @date 2019/11/7 16:46
     */
    public function getPackagePath($data)
    {
        //校验超时问题
        $this->timeOut(60*60);

        //1. 检查同时下载客户端数量
        $online = $this->online(200);


        if(!$online){
            throw new CustomException('同时下载数量已达上限,请等待!', '202');
        }


        $data['type'] = isset($data['type']) ? $data['type'] : 'client';

        //1. 数据校验
        $checkArr = array('os', 'type');

        foreach ($checkArr as $k => $v){
            if(!isset($data[$v]) ){
                throw new CustomException($v.'为必须参数', '202');
            }
        }

        //判断授权时间
        $authInfo = Db::name('server_auth_module')->where('module_key', 'client')->find();
        if(!$authInfo){
            throw new CustomException('为查询到客户端授权信息', '202');
        }

        $authServer = new ServerAuthService();
        $systemTime = $authServer->getSystemTime();

        if($authInfo['etime'] != 0 && $systemTime > $authInfo['etime']){
            throw new CustomException('授权已到期,暂不支持更新', '202');
        }


        //查询更新包数据
        $list = Db::name('server_update_list')
            ->where('type', strtolower($data['type']))
            ->where('os', strtolower($data['os']))
            ->select();


        $urlHeader = request()->domain() . '/';//协议头

        $jsonArr = array();
        foreach ($list as $k => $v){
            $v['url'] = substr($v['url'], strpos($v['url'],'public/') + strlen('public/'));
            if (file_exists($v['url'])) {
                $jsonArr[$k]['hash'] = $v['hash'];
                $jsonArr[$k]['url'] = $urlHeader.$v['url'];
                $jsonArr[$k]['name'] = $v['name'];
                $jsonArr[$k]['version'] = $v['version'];
                $jsonArr[$k]['desc'] = $v['desc'];
                $jsonArr[$k]['ext'] = $v['ext'];
            }
        }

        if(empty($jsonArr)){
            throw new CustomException('当前已是最新版本', '202');
        }

        //3. 添加数据到系统更新表中
        $ip = $_SERVER['REMOTE_ADDR'];//客户端ip


        $data_info = Db::name('server_update')->where(['ip' => $ip])->find();
        if($data_info){
            $updateData = array(
                'status' => 1,
                'last_time' => time(),
            );
            Db::name('server_update')->where(['id' => $data_info['id']])->update($updateData);
        }else{
            $addData = array(
                'ip' => $ip,
                'status' => 1,
                'last_time' => time(),
                'ctime' => time(),
            );
            Db::name('server_update')->insert($addData);
        }

        //4. 返回数据
        return $jsonArr;
    }


    /**
     * @name 客户端更新包下载结果
     * @param $data
     * @return bool
     * @author wx
     * @date 2019/11/7 16:47
     */
    public function downloadResult($data)
    {
        $fileLog = '../runtime/ServerUpdate.log';
        $params = $_SERVER['REMOTE_ADDR'].'下载结果:'.date('Y-m-d H:i:s',time()).PHP_EOL.json_encode($data,JSON_UNESCAPED_UNICODE).PHP_EOL;
        file_put_contents($fileLog,$params,FILE_APPEND);


        //1. 数据校验
        $checkArr = array('old_version', 'new_version', 'os', 'result','desc', 'hostkey');

        foreach ($checkArr as $k => $v){
            if(!isset($data[$v]) ){
                throw new CustomException($v.'为必须参数', '202');
            }
        }

        $ip = $_SERVER['REMOTE_ADDR'];//客户端ip

        //2.记录更新日志
        $downloadRes = $data['result'];

        $host_id = Db::name('host')->where('hostkey',$data['hostkey'])->value('id');
        $host_id = empty($host_id) ? 0 : $host_id;

        //添加系统更新日志
        $add_update_log = array(
            'old_version' => $data['old_version'],
            'new_version' => $data['new_version'],
            'ip' => $ip,
            'host_id' => $host_id,
            'type' => 1,
            'status' => $downloadRes,
            'desc' => $data['desc'],
            'ctime' => time()
        );
        Db::name('server_update_log')->insert($add_update_log);



        //3. 修改下载任务表
        Db::name('server_update')->where(['ip' => $ip])->update(['status' => $downloadRes]);

        return 'success';
    }

    /**
     * @name 客户端更新包执行结果
     * @author wx
     * @date 2019/11/7 16:52
     */
    public function updateResult($data)
    {
        $fileLog = '../runtime/ServerUpdate.log';
        $params = $_SERVER['REMOTE_ADDR'].'更新结果:'.date('Y-m-d H:i:s',time()).PHP_EOL.json_encode($data,JSON_UNESCAPED_UNICODE).PHP_EOL;
        file_put_contents($fileLog,$params,FILE_APPEND);


        //type 1=> 客户端 2 => 服务端
        $check_a = ['old_version', 'new_version', 'desc', 'result', 'hostkey', 'type'];
        foreach ( $check_a as $v)
        {
            if(!isset($data[$v]))
            {
                throw new ValidateException($v.'为必要参数', 422);
            }
        }

        $ip = $_SERVER['REMOTE_ADDR'];//客户端ip

        //查询host_id
        $host_id = Db::name('host')->where('hostkey',$data['hostkey'])->value('id');
        $host_id = empty($host_id) ? 0 : $host_id;

        //2. 添加系统更新日志
        $update_server = new ServerUpdateLogService();
        $add_update_log = array(
            'old_version' => $data['old_version'],
            'new_version' => $data['new_version'],
            'ip' => $ip,
            'host_id' => $host_id,
            'type' => $data['type'],
            'status' => $data['result'],
            'desc' => $data['desc'],
            'ctime' => time()
        );

        $update_server->add($add_update_log);

        //修改客户端状态
        $hostServer = new Host();
        $hostServer->modify(['id' => $host_id ], [
                'client_version' => $data['new_version'],
                'client_update_status' => $data['result']
            ]);


        return 'success';
    }

    /**
     * @name 延时
     * @param int $expires_time
     * @return int
     * @author wx
     * @date 2020/5/9 16:56
     */
    public function timeOut($expires_time = 600)
    {
        $data = Db::name('server_update')->where('status',1)->select();

        $updateStatus = [];
        foreach ($data as $k => $v){
            if ($v['last_time'] + $expires_time < time()) {
                $updateStatus[] = $v['id'];
            }
        }

        if($updateStatus){//修改状态
            Db::name('server_update')->whereIn('id', $updateStatus)->update(['status' => 4]);
        }
    }
}